/**
 * Copyright (c) 2018-2099, Chill Zhuang 庄骞 (bladejava@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springblade.modules.restaurant.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.modules.restaurant.entity.Area;
import org.springblade.modules.restaurant.entity.Task;
import org.springblade.modules.restaurant.entity.TaskRecord;
import org.springblade.modules.restaurant.enums.TaskRecordStatusEnums;
import org.springblade.modules.restaurant.mapper.TaskMapper;
import org.springblade.modules.restaurant.mapper.TaskRecordMapper;
import org.springblade.modules.restaurant.service.IAreaService;
import org.springblade.modules.restaurant.service.ITaskRecordService;
import org.springblade.modules.restaurant.vo.*;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * 任务记录 服务实现类
 *
 * @author Blade
 * @since 2025-01-21
 */
@Slf4j
@Service
@AllArgsConstructor
public class TaskRecordServiceImpl extends BaseServiceImpl<TaskRecordMapper, TaskRecord> implements ITaskRecordService {
	private final IAreaService areaService;
	private final TaskMapper taskMapper;

	@Override
	public IPage<TaskRecordVO> selectTaskRecordPage(IPage<TaskRecordVO> page, TaskRecordVO taskRecord) {
		return page.setRecords(baseMapper.selectTaskRecordPage(page, taskRecord));
	}

	@Override
	public BigDecimal getAreaMonthScore(List<Long> areaIds, DateTime startTime, DateTime endTime) {

		List<TaskRecord> taskRecords = lambdaQuery().in(TaskRecord::getAreaId, areaIds)
			.between(TaskRecord::getCreateTime, startTime, endTime)
			.eq(BaseEntity::getStatus, TaskRecordStatusEnums.AUDITED.getCode())
			.list();

		if (taskRecords != null && !taskRecords.isEmpty()) {
			BigDecimal score = taskRecords.stream().map(TaskRecord::getScore).reduce(BigDecimal.ZERO, BigDecimal::add);
			return score.divide(new BigDecimal(taskRecords.size()), 2, RoundingMode.HALF_UP);
		}
		return BigDecimal.ZERO;
	}

	@Override
	public boolean addTask(TaskRecordVO taskRecordVO) {
		TaskRecord item = new TaskRecord();
		BeanUtil.copyProperties(taskRecordVO, item);

		String taskTime = DateUtil.formatDate(DateUtil.date());
		item.setTaskTime(taskTime);
		item.setType(1);
		if (ObjectUtil.isEmpty(taskRecordVO.getInspectorId())) {
			// 检查人即下发人
			item.setInspectorId(SecureUtil.getUserId());
			item.setInspectorName(SecureUtil.getUserName());
		}
		item.setStatus(TaskRecordStatusEnums.WAIT_SUBMIT.getCode());
		return save(item);
	}

	@Override
	public boolean assignTask(Task task, TaskRecordVO taskRecordVO) {
		String taskTime = DateUtil.formatDate(DateUtil.date());

		TaskRecord item = new TaskRecord();
		item.setTaskTime(taskTime);
		item.setStatus(TaskRecordStatusEnums.WAIT_SUBMIT.getCode());

		if (ObjectUtil.isEmpty(taskRecordVO.getInspectorId())) {
			// 检查人即下发人
			item.setInspectorId(SecureUtil.getUserId());
			item.setInspectorName(SecureUtil.getUserName());
		} else {
			item.setInspectorId(taskRecordVO.getInspectorId());
			item.setInspectorName(taskRecordVO.getInspectorName());
		}
		// 负责人
		item.setUserId(taskRecordVO.getUserId());
		item.setUserName(taskRecordVO.getUserName());

		item.setTaskId(task.getId());
		item.setTaskName(StrUtil.isNotBlank(taskRecordVO.getTaskName()) ? taskRecordVO.getTaskName() : task.getTaskName());
		item.setSampleGraph(task.getSampleGraph());
		item.setAnnouncements(task.getAnnouncements());
		item.setType(task.getType());
		item.setTimeType(ObjectUtil.isNotEmpty(taskRecordVO.getTimeType()) ? taskRecordVO.getTimeType() : task.getTimeType());

		item.setRemark(taskRecordVO.getRemark());
		item.setDeadline(taskRecordVO.getDeadline());
		item.setInspectDeadline(taskRecordVO.getInspectDeadline());

		String areaId = ObjectUtil.isNotEmpty(taskRecordVO.getAreaId()) ? String.valueOf(taskRecordVO.getAreaId()) : task.getAreaIds();
		Area area = areaService.getById(areaId);
		if (area == null) {
			log.error("任务区域不存在,任务ID:{},区域ID:{}", task.getId(), areaId);
		} else {
			item.setAreaId(Long.valueOf(areaId));
			item.setAreaName(area.getAreaName());
		}

		taskMapper.deleteById(task);
		return save(item);
	}

	@Override
	public boolean saveDraft(TaskDraftVO taskVO) {
		if (ObjectUtil.isNotEmpty(taskVO.getId())) {
			TaskRecord taskRecord = getById(taskVO.getId());
			if (taskRecord != null) {
				taskRecord.setStatus(TaskRecordStatusEnums.WAIT_SUBMIT.getCode());
				taskRecord.setUserPicture(taskVO.getUserPicture());
				taskRecord.setSuggestion(taskVO.getSuggestion());
				return updateById(taskRecord);
			}
		}
		return false;
	}

	@Override
	public boolean submitTask(TaskSubmitVO taskVO) {
		if (ObjectUtil.isNotEmpty(taskVO.getId())) {
			TaskRecord taskRecord = getById(taskVO.getId());
			if (taskRecord != null) {
				taskRecord.setStatus(TaskRecordStatusEnums.SUBMITTED.getCode());
				taskRecord.setUserPicture(taskVO.getUserPicture());
				taskRecord.setSuggestion(taskVO.getSuggestion());
				taskRecord.setSubmitTime(DateUtil.date());
				return updateById(taskRecord);
			}
		}
		return false;
	}

	@Override
	public boolean checkTask(TaskCheckVO taskVO) {
		if (ObjectUtil.isNotEmpty(taskVO.getId())) {
			TaskRecord taskRecord = getById(taskVO.getId());
			if (taskRecord != null) {
				taskRecord.setStatus(TaskRecordStatusEnums.AUDITED.getCode());
				taskRecord.setScore(taskVO.getScore() == null ? BigDecimal.ZERO : taskVO.getScore());
				taskRecord.setComment(taskVO.getComment());
				taskRecord.setCommentPicture(taskVO.getCommentPicture());
				taskRecord.setCommentTime(DateUtil.date());
				return updateById(taskRecord);
			}
		}
		return false;
	}

	@Override
	public boolean rejectTask(TaskRejectVO taskVO) {
		if (ObjectUtil.isNotEmpty(taskVO.getId())) {
			TaskRecord taskRecord = getById(taskVO.getId());
			if (taskRecord != null) {
				taskRecord.setStatus(TaskRecordStatusEnums.WAIT_SUBMIT.getCode());
				taskRecord.setRejectReason(taskVO.getRejectReason());
				taskRecord.setRejectTime(DateUtil.date());
				taskRecord.setDeadline(taskVO.getDeadline());
				return updateById(taskRecord);
			}
		}
		return false;
	}

	@Override
	public long waitTaskCount(Long userId, String role) {
		LambdaQueryWrapper<TaskRecord> wrapper = Wrappers.lambdaQuery();
		if (role.contains("employee")) {
			// 如果是员工  查询自己待提交的任务
			wrapper.eq(TaskRecord::getStatus, TaskRecordStatusEnums.WAIT_SUBMIT.getCode())
				.eq(TaskRecord::getUserId, userId);
		} else if (role.contains("dept_manager")) {
			wrapper
				.in(TaskRecord::getStatus, TaskRecordStatusEnums.SUBMITTED.getCode(), TaskRecordStatusEnums.WAIT_SUBMIT.getCode())
				.and(w -> w.eq(TaskRecord::getUserId, userId).or().eq(TaskRecord::getInspectorId, userId));
		} else {
			wrapper
				.in(TaskRecord::getStatus, TaskRecordStatusEnums.SUBMITTED.getCode(), TaskRecordStatusEnums.WAIT_SUBMIT.getCode());
		}
		wrapper.eq(TaskRecord::getTaskTime, DateUtil.formatDate(DateUtil.date()));
		return count(wrapper);
	}

	@Override
	public long taskCount(Long userId, String role) {
		LambdaQueryWrapper<TaskRecord> wrapper = Wrappers.lambdaQuery();
		if (role.contains("employee")) {
			// 如果是员工  查询自己待提交的任务
			wrapper.eq(TaskRecord::getUserId, userId);
		} else if (role.contains("dept_manager")) {
			wrapper.and(w -> w.eq(TaskRecord::getUserId, userId).or().eq(TaskRecord::getInspectorId, userId));
		}
		wrapper.eq(TaskRecord::getTaskTime, DateUtil.formatDate(DateUtil.date()));
		return count(wrapper);
	}

	@Override
	public boolean setExecutor(TaskSetExecutorVO task) {
		if (ObjectUtil.isNotEmpty(task.getId())) {
			TaskRecord taskRecord = getById(task.getId());
			if (taskRecord != null) {
				taskRecord.setUserId(task.getUserId());
				taskRecord.setUserName(task.getUserName());
				return updateById(taskRecord);
			}
		}
		return false;
	}

	@Override
	public boolean scoreTask(TaskScoreVO taskVO) {
		if (ObjectUtil.isNotEmpty(taskVO.getId())) {
			TaskRecord taskRecord = getById(taskVO.getId());
			if (taskRecord != null) {
				taskRecord.setScore(taskVO.getScore());
				taskRecord.setDeductPoints(taskVO.getDeductPoints());
				return updateById(taskRecord);
			}
		}
		return false;
	}
}
